package com.wfh.aigenerator.controller;

import com.wfh.aigenerator.service.SseService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import java.io.IOException;
import jakarta.servlet.http.HttpServletResponse;

/**
 * @author fenghuanwang
 */
@RestController
@Slf4j
@RequestMapping("/sse") // context-path=/api 会自动加前缀
public class SseController {

    @Resource
    private SseService sseService;

    /**
     * 建立 SSE 连接
     */
    @GetMapping(value = "/connect/{taskId}", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public SseEmitter connect(@PathVariable Long taskId, HttpServletResponse response) {
        log.info("✅ 收到 SSE 连接请求，taskId: {}", taskId);

        try {
            // 关键响应头，避免代理缓冲，保持长连接
            response.setHeader("Cache-Control", "no-cache");
            response.setHeader("Connection", "keep-alive");
            response.setHeader("X-Accel-Buffering", "no");

            // 30分钟超时
            SseEmitter emitter = sseService.connect(taskId, 30 * 60 * 1000L);
            log.info("✅ SSE 连接已建立，taskId: {}", taskId);
            // 发送首个事件，确保连接立即生效并刷新到客户端
            try {
                sseService.sendMessage(taskId, "connected", "SSE connected");
            } catch (Exception sendEx) {
                log.warn("首次发送 connected 事件失败，taskId: {}", taskId, sendEx);
            }
            return emitter;
        } catch (Exception e) {
            log.error("❌ 创建 SSE 连接失败，taskId: {}", taskId, e);
            return buildErrorEmitter(taskId, "SSE 连接失败: " + e.getMessage());
        }
    }

    /**
     * 构建一个返回错误信息的 SseEmitter
     */
    private SseEmitter buildErrorEmitter(Long taskId, String errorMsg) {
        SseEmitter emitter = new SseEmitter(10_000L); // 10秒后超时

        emitter.onTimeout(() -> {
            log.warn("Error emitter 超时，taskId: {}", taskId);
            emitter.complete();
        });

        emitter.onError((ex) -> {
            log.error("Error emitter 发生错误，taskId: {}", taskId, ex);
        });

        emitter.onCompletion(() -> {
            log.info("Error emitter 已完成，taskId: {}", taskId);
        });

        try {
            emitter.send(SseEmitter.event()
                    .name("error")
                    .data(errorMsg)
            );
            emitter.complete();
        } catch (IOException ex) {
            log.error("发送错误事件失败", ex);
            emitter.completeWithError(ex);
        }

        return emitter;
    }
}